package com.sojson.annotation.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import com.sojson.annotation.Log;
import com.sojson.constant.ConstantServlet;
import com.sojson.util.annotation.AnnoUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 操作日志记录处理
 *
 * @author lzlg
 */
@Slf4j
@Aspect
@Component
public class LogAspect {

    /** 配置织入点 */
    @Pointcut("@annotation(" + ConstantServlet.PACKAGE_DEFAULT_ANNOTATION_ALL + ".Log)")
    public void logPointCut() {}

    /**
     * 请求处理之前
     * 
     * @param joinPoint 切点
     */
    @Before("logPointCut()")
    public void before(JoinPoint joinPoint) {
        System.out.println("请求执行之前！");
        System.out.println("切点: " + joinPoint);
    }

    /**
     * 请求处理完之后
     * 
     * @param joinPoint     切点
     * @param jsonResult    响应的数据
     */
    @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
    public void afterReturning(JoinPoint joinPoint, Object jsonResult) {
        System.out.println("请求执行之后！");
        handleLog(joinPoint, null, jsonResult);
    }

    /**
     * 拦截异常操作(先处理切面的异常,然后处理全局异常)
     *
     * @param joinPoint 切点
     * @param e         异常
     */
    @AfterThrowing(value = "logPointCut()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
        System.out.println("请求异常之后！");
        handleLog(joinPoint, e, null);
    }

    protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult) {
        System.out.println("响应的数据: " + jsonResult);
        System.out.println("异常的数据: " + e);
        try {
            // 获得注解
            Log controllerLog = AnnoUtil.getAnnoByMethod(joinPoint, Log.class);
            if (controllerLog == null) {
                return;
            }
        } catch (Exception exp) {
            // 记录本地异常日志
            log.error("==前置通知异常==");
            log.error("异常信息:{}", exp.getMessage());
            exp.printStackTrace();
        }
    }

}